import java.util.*;
// 记录类 初始化记录 每一个对象添加到动态数组transactions
class Transaction {
    String date;
    double amount;
    String category;
    String remark;

    Transaction(String date, double amount, String category, String remark) {
        this.date = date;
        this.amount = amount;
        this.category = category;
        this.remark = remark;
    }
}
public class PersonalFinanceManager {
    private ArrayList<Transaction> transactions = new ArrayList<>();
    private Scanner scanner = new Scanner(System.in);
    private boolean isRunning = true; // 控制程序运行状态


    // 主运行方法，显示菜单并处理用户输入
    public void run() {
        while (isRunning) {
            showMenu();
            int choice = getValidMenuOption(); // 获取有效的菜单选项
            handleMenuChoice(choice);
        }
    }

    // 显示菜单
    private void showMenu() {
        System.out.println("=================================");
        System.out.println("欢迎使用个人账单管理系统");
        System.out.println("=================================");
        System.out.println("请选择操作：");
        System.out.println("1. 记录收入");
        System.out.println("2. 记录支出");
        System.out.println("3. 查看所有账单");
        System.out.println("4. 查询账单");
        System.out.println("5. 退出系统");
        System.out.println("=================================");
    }

    // 获取有效的菜单选项
    private int getValidMenuOption() {
        int choice = -1;
        while (choice < 1 || choice > 5) {
            System.out.print("请输入选项序号：");
            if (scanner.hasNextInt()) {
                choice = scanner.nextInt();
                if (choice < 1 || choice > 5) {
                    System.out.println("错误：请输入1到5之间的数字。");
                }
            } else {
                System.out.println("错误：请输入有效的数字。");
                scanner.next(); // 清除无效输入
            }
        }
        scanner.nextLine(); // 消耗换行符
        return choice;
    }

    // 处理用户的菜单选择
    private void handleMenuChoice(int choice) {
        switch (choice) {
            case 1 -> recordIncome();// 收入
            case 2 -> recordExpense();// 支出
            case 3 -> displayTransactions();// 展示所有菜单
            case 4 -> queryTransactions();
            case 5 -> exitSystem();
        }
    }
    // 返回主菜单
    private void returnToMenu() {
        System.out.println("按任意键返回主菜单...");
        scanner.nextLine();
    }

    // 退出系统
    public void exitSystem() {
        System.out.println("感谢使用个人账单管理系统，程序已退出。");
        isRunning = false;
    }
    // 验证日期格式
    private String getValidDate() {
        String date = "";
        boolean isValid = false;
        while (!isValid) {
            System.out.print("日期（YYYY-MM-DD）：");
            date = scanner.nextLine();
            if (date.matches("\\d{4}-\\d{2}-\\d{2}")) {
                isValid = true;
            } else {
                System.out.println("错误：请输入正确的日期格式（YYYY-MM-DD）。");
            }
        }
        return date;
    }
    // 收入
    public void recordIncome() {
        System.out.println("请输入收入信息：");
        String date = getValidDate();
        System.out.print("输入收入金额: ");
        double amount = -1; // 初始化为负数以便进行验证
        while(amount<=0){
            if(scanner.hasNextDouble()){// 处理输入的下一个数据是无效数据 有效数据：数字123, 45.67, -89.1，1.23e4（表示 12300）等 True
                amount = scanner.nextDouble();// 读取输入
                if (amount <= 0) { // 验证金额是否为正数
                    System.out.println("错误：金额必须为正数，请重新输入。");
                    System.out.print("输入收入金额: ");
                }
            }else{// 无效数据 False
                System.out.println("错误：请输入有效的数字。");
                System.out.print("输入收入金额: ");
                scanner.next(); // 清除无效输入 防止程序因为错误输入而卡住。 继续循环
            }
//            scanner.nextLine(); // 消耗换行符
        }
        scanner.nextLine(); // Consume newline
        System.out.print("输入收入类别(如工资、奖金等): ");
        String category = scanner.nextLine();// 读取并返回用户在控制台输入的整行文本，直到遇到换行符（即用户按下“Enter”键）
        System.out.print("输入备注: ");
        String remark = scanner.nextLine();
        // 把记录的对象添加到动态数组末尾
        transactions.add(new Transaction(date, amount, category, remark));
        System.out.println("收入记录成功！");
        returnToMenu();
    }
    // 支出
    public void recordExpense() {
        System.out.println("请输入支出信息：");
        String date = getValidDate();
        System.out.print("输入支出金额: ");
        double amount = -1; // 初始化为负数以便进行验证
        while(amount<=0){
            if(scanner.hasNextDouble()){// 处理输入的下一个数据是无效数据 有效数据：数字123, 45.67, -89.1，1.23e4（表示 12300）等 True
                amount = scanner.nextDouble();// 读取输入
                if (amount <= 0) { // 验证金额是否为正数
                    System.out.println("错误：金额必须为正数，请重新输入。");
                }
            }else{// 无效数据 False
                System.out.println("错误：请输入有效的数字。");
                scanner.next(); // 清除无效输入 防止程序因为错误输入而卡住。 继续循环
            }
//            scanner.nextLine(); // 消耗换行符
        }
        scanner.nextLine(); // 消耗换行符号
        System.out.print("输入支出类别(如餐饮、交通、购物等): ");
        String category = scanner.nextLine();// 输入一行 直到遇到换行符（回车）终止 读取后返回的是字符串
        System.out.print("输入备注: ");
        String remark = scanner.nextLine();
        transactions.add(new Transaction(date, -amount, category, remark));
        System.out.println("支出记录成功！");
        returnToMenu();
    }

    // 账单展示
    public void displayTransactions() {
        System.out.println("所有账单记录：");
        System.out.println("收入：");
        for (Transaction t : transactions) {
            if (t.amount > 0) {
                System.out.printf("日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n",
                        t.date, t.amount, t.category, t.remark);
            }
        }
        System.out.println("支出：");
        for (Transaction t : transactions) {
            if (t.amount < 0) {
                System.out.printf("日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n",
                        t.date, -t.amount, t.category, t.remark);
            }
        }
    }

    // 账单查询
    public void queryTransactions() {
        System.out.println("查询账单记录：");
        System.out.print("输入类别、指定日期（YYYY-MM-DD）或日期范围（格式 YYYY-MM-DD 到 YYYY-MM-DD），输入'结束'退出: ");
        String input = scanner.nextLine();
        if (input.equalsIgnoreCase("结束")) {// 比较两个字符串，忽略大小写
            return;
        }
        String[] dateRange;
        if(input.contains("到")) {
            dateRange = input.split("到");// 以到分割input字符串 返回数组 如果没有到  返回一个这个字符串的数组
        }else{
            dateRange = new String[1]; // 创建一个长度为1的数组
            dateRange[0] = input.trim();; // 将input字符串赋值给dateRange[0]
            // 处理dateRange数组
        }
        String category1 = null;// 类别
        String specificDate = null;// 指定日期

        // 处理输入的日期范围或类别
        if (dateRange.length == 1) {
            // 检查是否为单一日期
            specificDate = dateRange[0].trim();
            // 检查是否为类别
            if (!specificDate.matches("\\d{4}-\\d{2}-\\d{2}")) {
                category1 = specificDate;
                System.out.println("按类别查询，类别为：" + category1); // 调试输出类别
            }
        } else {
            dateRange[0] = dateRange[0].trim();// 字符串前后去空字符
            dateRange[1] = dateRange[1].trim();
            // 检查日期合法性
            if (!dateRange[0].matches("\\d{4}-\\d{2}-\\d{2}") || !dateRange[1].matches("\\d{4}-\\d{2}-\\d{2}")) {
                System.out.println("错误：请输入有效的日期范围（格式 YYYY-MM-DD 到 YYYY-MM-DD）。");
                return;
            }
            // 进一步确保结束日期晚于开始日期
            if (dateRange[0].compareTo(dateRange[1]) > 0) {
                System.out.println("错误：结束日期必须晚于开始日期。");
                return;
            }
        }

        System.out.println("查询结果：");
        boolean hasResults = false; // 标志是否有结果
        for (Transaction t : transactions) {
            boolean matches = true;

            // 按类别查询
            if (category1 != null && !t.category.equals(category1.trim())) {// 匹配不到 赋值match为false 意思是没有查询到
                matches = false;
            }

            // 按日期范围查询
            if (dateRange.length == 2) {
                if (t.date.compareTo(dateRange[0]) < 0 || t.date.compareTo(dateRange[1]) > 0) {
                    matches = false;
                }
            }

            // 按指定日期查询
            if (specificDate != null && !specificDate.equals(t.date)) {
                matches = false;
            }

            // 输出查询结果
            if (matches) {
                hasResults = true; // 有匹配结果
                if (t.amount > 0) {
                    System.out.printf("收入 - 日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n",
                            t.date, t.amount, t.category, t.remark);
                } else {
                    System.out.printf("支出 - 日期: %s, 金额: %.2f, 类别: %s, 备注: %s%n",
                            t.date, -t.amount, t.category, t.remark);
                }
            }
        }
        if (!hasResults) {
            System.out.println("没有找到符合条件的账单记录。"); // 如果没有结果，给出提示
        }
        returnToMenu();// 返回主菜单
    }


    public static void main(String args[]){
        PersonalFinanceManager manager = new PersonalFinanceManager();
        manager.run(); // 启动菜单
//        // 记录收入
//        manager.recordIncome();
//        //记录支出
//        manager.recordExpense();
//        //查看所有账户
//        manager.displayTransactions();




    }

}
